#!/usr/bin/env python
# coding: utf-8

# # 1.函数
# ## 1.函数的定义
# > 1. 数学 ：        f(x) = ax + b
# > 2. python ： def fib(x):
# > 3. 编程思维 VS 数学思维
# >> 1.函数可以被定义名称,定义的关键字 <font style="color:red">**def**</font>
# >> 2.数学思维是写在同一行（定义函数 和 运算公式）,面向对象编程中 函数写多行,定义函数为单独一行
# >> 3.数学函数一般没有注释,而编程过程中,一般需要对函数进行注释描述（defining functions,课本p151）
# >> 4.数学中: ax+b 是计算公式,而编程中,我们将函数内容成为**函数体**,函数体要有一定的**缩进**
# >> 5.数学函数执行,将参数带入公式,编程中函数执行,将参数带入函数体
# 
# ## 2.关于函数的更多定义
# 
# > 1.函数的参数
# 
# >> 1.形式参数
# >> 2.实际参数
# >> 3.默认参数
# >> 4.位置参数
# >> 5.关键字参数

# # 2.函数的定义

# # 1.定义函数

# In[9]:


# 斐波那切数列： 0 1 1 2 3 5 8 13 21 34...
def fib(x):
    """列出指定x以内的斐波那切数列"""
    a,b = 0,1
    while a < x:
        print(a,end=" ")
        a,b = b, a+b
        


# In[10]:


fib(100)


# In[24]:


# 实践: 请大家写一个函数，这个函数可以打印“你好，xxx同学“
def hello(name):
    """显示问候语"""
    print("你好,%s同学~"%(name))


# # 2. 调用函数/使用函数
# ## 1.函数名（参数）
# ## 2.参数可以不存在

# In[25]:


hello("Lihua")


# In[18]:


def hello():
    """显示问候语"""
    print("hello,world")


# In[19]:


hello()


# In[20]:


# 回顾与思考
import time


# In[22]:


# sleep()需要给定一个时间（int）参数
time.sleep(3)


# In[ ]:


# localtime（）不需要给定参数
time.localtime()


# In[ ]:


> 3. 函数的优势
>> 1. 可以重复使用相同的功能，避免重复造轮子
>> 2. 使用者可以不了解函数本身，，只需要清楚如何使用即可
>> 3. 使用/调用方便，只需要清楚传递的 函数名及参数


# # 3.函数的参数

# > 1. 形式参数（形参）
# >> 1. 在**定义**的函数的时候定义的参数
# >> 2. 形式参数不占用内存
# > 2. 实际参数（实参）
# >> 1. 在**调用**的函数的时候传递的参数
# >> 2. 调用函数时，形式参数分配空间，传递实际参数，执行函数内容
# 
# > 1.形式参数：word
# 
# > 2.实际参数："jkdwbcegcfbehwkanijkrehwdncijkrwe"

# In[30]:


# 课本函数实践案例
def searchvowels(word):
    """显示文本中出现的元音字母有哪些"""
    vowels = set("aeiou")
    word = set(word)
    print(vowels & word)


# In[31]:


searchvowels("jkdwbcegcfbehwkanijkrehwdncijkrwe")


# In[32]:


* 在多个参数的情境下

> 1. 位置参数
>> 1. 在形式参数的定义中，有一定的先后顺序
>> 2. 在调用函数时，要考虑先后顺序
>> 3. 调用函数时，不仅要考虑参数位置，还需要考虑形式参数的个数

> 2. 关键字参数
>> 1. 在调用函数时，关键字参数可以不考虑形式参数的位置

> 3. 默认参数
>> 1. 调用函数时，可以省略传递的参数信息
>> 2. 调用函数时，如果给默认参数赋值，会替换默认参数的结果


# In[ ]:


* 参数注意事项实践

> 1. 位置参数和关键字同时使用
>> 1. Positional argument follows keyword argument(关键字参数均应放在位置参数后)
>> 2. 只要满足1的条件，剩余的关键字参数（多个）不考虑先后顺序

> 2.非默认参数和默认参数同时使用(定义参数)
>> 1. non-define argument follows keyword argument(默认参数均应放在位置参数后)
>> 2. 只要满足1的条件，剩余的关键字参数（多个）不考虑先后顺序
